package com.wytec.xywzxw.utils;

import com.github.pagehelper.PageInfo;
import com.wytec.xywzxw.bean.commonBean.CommonResult;
import com.wytec.xywzxw.constant.MyConstant;
import jakarta.servlet.http.HttpServletRequest;
import jodd.util.Base64;
import org.apache.tika.utils.StringUtils;
import org.lionsoul.ip2region.xdb.Searcher;
import org.springframework.core.io.ClassPathResource;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Component;
import org.springframework.util.FileCopyUtils;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import java.io.IOException;
import java.io.InputStream;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.nio.charset.StandardCharsets;
import java.security.SecureRandom;
import java.text.SimpleDateFormat;
import java.util.*;

@Component
public class CommonUtils {

    private static final String numberStr = "1234567890";
    private static final String numberCharStr = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";

    /**
     * 初始化的时候，将本类中的ymlConfig赋值给静态的本类变量
     */
    public static HttpServletRequest getRequest(){
        ServletRequestAttributes servletRequestAttributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        return servletRequestAttributes.getRequest();
    }
    public static Map<String, Object> createPageDataMap(List list){
        PageInfo pageInfo = new PageInfo(list);
        Map<String, Object> map = new HashMap<>(5);
        map.put(MyConstant.TOTALPAGESTR,pageInfo.getPages());
        map.put(MyConstant.TOTALSIZESTR,pageInfo.getTotal());
        map.put(MyConstant.PAGESTR,pageInfo.getPageNum());
        map.put(MyConstant.SIZESTR,pageInfo.getPageSize());
        map.put(MyConstant.LISTSTR,list);
        return map;
    }

    /**
     * 生成Token
     * @return token
     */
    public static String createToken(){
        SecureRandom random =new SecureRandom();
        byte[] bytes = new byte[24];
        random.nextBytes(bytes);
        return Base64.encodeToString(bytes);
    }

    public static String getCurrentTimeFormat(String format){
        Date date = new Date();
        SimpleDateFormat dateFormat = new SimpleDateFormat(format);
        return dateFormat.format(date);
    }
    public static Map<String,String> getIpRegion(String ip){
        if (ip == null || ip.isEmpty()) {
            ip = CommonUtils.getIpAddr();
        }
        Searcher searcher = null;
            try {
                //这里通过流获取 解决jar包无法读取文件问题
                ResponseEntity<byte[]> testPage = test();
                searcher = Searcher.newWithBuffer(testPage.getBody());
            } catch (IOException e) {
                CommonResult.failed(e.getMessage());
            }
        String region = null;
        try {
            region = searcher.search(ip);
        } catch (Exception e) {
            CommonResult.failed(e.getMessage());
        }
        region = ip + "|" + region;
        String[] arrays = region.split("\\|");
        Map<String,String>map = new LinkedHashMap<>();
        map.put("ip","0".equals(arrays[0])?"":arrays[0]);
        map.put("region","0".equals(arrays[1])?"":arrays[1]);
        map.put("province","0".equals(arrays[3])?"":arrays[3]);
        map.put("city","0".equals(arrays[4])?"":arrays[4]);
        map.put("operator","0".equals(arrays[5])?"":arrays[5]);
        return map;
    }
    private static ResponseEntity<byte[]> test() throws IOException {
        ClassPathResource classPathResource = new ClassPathResource("db/ip2region.xdb");
        String filename = classPathResource.getFilename();
        InputStream inputStream = classPathResource.getInputStream();
        byte[] bytes = FileCopyUtils.copyToByteArray(inputStream);
        String fileName = new String(filename.getBytes(StandardCharsets.UTF_8), StandardCharsets.ISO_8859_1);// 为了解决中文名称乱码问题
        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.APPLICATION_OCTET_STREAM);
        headers.setContentDispositionFormData("attachment", fileName);
        return new ResponseEntity<>(bytes, headers, HttpStatus.CREATED);
    }

    /**
     * @return Ip地址
     */
    public static String getIpAddr() {
        HttpServletRequest request = getRequest();
        String ipAddress = null;
        String unknown = "unknown";
        String localIp = "127.0.0.1";
        String separator = ",";
        int addressLen = 15;
        try {
            ipAddress = request.getHeader("x-forwarded-for");
            if (ipAddress == null || ipAddress.isEmpty() || unknown.equalsIgnoreCase(ipAddress)) {
                ipAddress = request.getHeader("Proxy-Client-IP");
            }
            if (ipAddress == null || ipAddress.isEmpty() || unknown.equalsIgnoreCase(ipAddress)) {
                ipAddress = request.getHeader("WL-Proxy-Client-IP");
            }
            if (ipAddress == null || ipAddress.isEmpty() || unknown.equalsIgnoreCase(ipAddress)) {
                ipAddress = request.getRemoteAddr();
                if (ipAddress.equals(localIp)) {
                    // 根据网卡取本机配置的IP
                    InetAddress inet = null;
                    try {
                        inet = InetAddress.getLocalHost();
                        ipAddress = inet.getHostAddress();
                    } catch (UnknownHostException e) {
                        e.printStackTrace();
                    }
                }
            }
            // 对于通过多个代理的情况，第一个IP为客户端真实IP,多个IP按照','分割
            if (ipAddress != null && ipAddress.length() > addressLen) {
                if (ipAddress.indexOf(separator) > 0) {
                    ipAddress = ipAddress.substring(0, ipAddress.indexOf(separator));
                }
            }
        } catch (Exception e) {
            ipAddress="";
        }
        return ipAddress;
    }
    static public String createCaptchaCode(int len) {
        return createRandomCodeTemplate(numberStr,len);
    }
    static public String createRandomCode(int len){
        return createRandomCodeTemplate(numberCharStr,len);
    }
    static private String createRandomCodeTemplate(String chars,int len) {
        String linkNo = "";
        char[] m = chars.toCharArray();
        if (len > chars.length()){
            len = chars.length();
        }
        for (int j = 0; j < len; j++) {
            char c = m[(int) (Math.random() * chars.length())];
            // 保证随机数之间没有重复的
            if (linkNo.contains(String.valueOf(c))) {
                j--;
                continue;
            }
            linkNo = linkNo + c;
        }
        return linkNo;
    }
    public static String changeTimeStamps(long timeStamps,String dateFormatter){
        Date date = new Date(timeStamps);
        SimpleDateFormat sdf = new SimpleDateFormat(dateFormatter);
        return sdf.format(date);
    }
    // 获取转换后的数据单位
    public static String getConversionFlows(String flow){
        String sizeStr = "1024";
        int sizeScale = 2;
        if (null == flow || flow.isEmpty() || flow.equals("null")) {
            return "0.00 KB";
        }
        if(StringUtils.isBlank(flow) || Double.valueOf(flow).longValue() < 10){
            return "0.00 KB";
        }
        String kbStr = div(flow, sizeStr, sizeScale);
        if(compareBigDecimal(kbStr, sizeStr) < 0){
            return kbStr + " KB";
        }
        String mbStr = div(kbStr, sizeStr, sizeScale);
        if(compareBigDecimal(mbStr, sizeStr) < 0){
            return mbStr + " MB";
        }
        String gbStr = div(mbStr, sizeStr, sizeScale);
        if(compareBigDecimal(gbStr, sizeStr) < 0){
            return gbStr + " GB";
        }
        String tbStr = div(gbStr, sizeStr, sizeScale);
        return tbStr+ " TB";
    }
    private static String div(String str1, String str2, int scale) {
        BigDecimal b1 = new BigDecimal(str1);
        BigDecimal b2 = new BigDecimal(str2);
        BigDecimal divide = b1.divide(b2, scale, RoundingMode.HALF_UP);
        return divide.toString();
    }
    private static int compareBigDecimal(String str1, String str2) {
        BigDecimal b1 = new BigDecimal(str1);
        BigDecimal b2 = new BigDecimal(str2);
        return b1.compareTo(b2);
    }
}
